package com.epin.business.commons.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.epin.base.exception.check.RecordQuoteException;
import com.epin.base.plugins.AbstractBean;
import com.epin.base.plugins.BaseController;
import com.epin.business.commons.entity.UploadFile;
import com.epin.business.commons.service.UploadFileService;
import com.epin.util.DateUtil;
import com.epin.util.FilePropertyUtil;
import com.epin.util.FileUtils;
import com.epin.util.SessionUtil;
import com.feilong.core.Validator;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;


/**
 * 
 * @author DELL
 *
 */
@Controller
@RequestMapping(value = "")
public class FileController extends BaseController {
	
	private static Logger logger = LoggerFactory.getLogger(FileController.class);
	
	
	@Autowired
	private UploadFileService uploadFileService;
	
	
	
	
	
	/**
	 * 保存文件数据
	 */
	@RequestMapping(value = "/file/saveFile", method = RequestMethod.POST)
	@ResponseBody
	public AbstractBean saveFile(String fileDatas, String businessId, Integer businessType){
		
		if (Validator.isNullOrEmpty(fileDatas) || Validator.isNullOrEmpty(businessId) ||
				Validator.isNullOrEmpty(businessType)) {
			return fail("参数为空");
		}
		
		List<UploadFile> files = JSON.parseObject(fileDatas, new TypeReference<List<UploadFile>>() {});
		
		for (UploadFile file : files) {
			if (Validator.isNullOrEmpty(file.getId())) {
				file.setBusinessId(businessId);
				file.setBusinessType(businessType);
				file.setUploaderName(SessionUtil.getCurrentUser().getName());
				file.setCreateDate(new Date(System.currentTimeMillis()));
			}
			file.setUpdateDate(new Date(System.currentTimeMillis()));
		}
		
		return uploadFileService.insertOrUpdateBatch(files) ? success() : error();
	}
	
	
	
	/**
	 * 删除文件数据
	 */
	@RequestMapping(value = "/file/deleteFiles", method = RequestMethod.POST)
	@ResponseBody
	public AbstractBean deleteFiles(Integer[] ids) {
		
		try {
			return uploadFileService.deleteFilesByIds(Arrays.asList(ids)) ? success() : error();
		} catch (RecordQuoteException e) {
			return fail(e.getMessage());
		}
	}
	
	
	
	/**
	 * 修改文件数据状态
	 */
	@RequestMapping(value = "/file/statusFiles", method = RequestMethod.POST)
	@ResponseBody
	public AbstractBean statusFiles(Integer[] ids, Integer status) {
		
		List<UploadFile> files = new ArrayList<>();
		
		for (Integer id : ids) {
			UploadFile file = new UploadFile();
			
			file.setId(id);
			file.setStatus(status);
			file.setUpdateDate(new Date(System.currentTimeMillis()));
			
			files.add(file);
		}
		
		return uploadFileService.updateBatchById(files) ? success() : error();
	}
	
	
	
	/**
	 * 查看文件数据
	 */
	@RequestMapping(value = "/file/loadFile", method = RequestMethod.GET)
	@ResponseBody
	public AbstractBean loadFile(String businessId, Integer businessType){
		
		Map<String, Object> columnMap = new HashMap<>();
		
		columnMap.put("BUSINESS_ID", businessId);
		columnMap.put("BUSINESS_TYPE", businessType);
		
		List<UploadFile> files = uploadFileService.selectByMap(columnMap);
		
		return success(files);
	}
	
	
	
	
	
	/**
	 * 上传文件到硬盘
	 */
	@SuppressWarnings("unused")
	@RequestMapping(value = "/file/uploadMore", method = RequestMethod.POST)
	@ResponseBody
	public AbstractBean uploadMore(HttpServletRequest request, HttpServletResponse response, 
			@RequestParam("uploadFile")MultipartFile[] uploadFile, @RequestParam(value = "fileName", required = false)String defineName, 
			@RequestParam(value = "path", required = false)String definePath, @RequestParam(value = "dayPath", required = false)String dayPath, 
			@RequestParam(value = "canMark", required = true, defaultValue = "1")Integer canMark) {
		
		Map<String, Object> model = new HashMap<String, Object>();
		
		if(StringUtils.isBlank(dayPath)){
			String dateStr = DateUtil.formate2Date(new Date());
	        String[] d = dateStr.split("-");
	        dayPath = d[0] + "/" + d[1] + "/" + d[2] + "/";
		}
		String filePath = FilePropertyUtil.getFilePathProperty().getProperty("temPath");
		
		String uploadPath = "";
		if(StringUtils.isBlank(definePath)){
			uploadPath = "/upload/" + dayPath;
		}else{
			uploadPath = definePath + "/"+dayPath;
		}
		filePath += uploadPath;
	    if (!new File(filePath).isDirectory()) {
			new File(filePath).mkdirs();
		}
	    
	    if (uploadFile != null) {
	    	for (int n = 0; n < uploadFile.length; n++) {
	    		MultipartFile file = uploadFile[n];
	    		
				String fileName = "";
                String originalFileName = file.getOriginalFilename();
                String fileNew = originalFileName.substring(0, originalFileName.lastIndexOf('.'));
                String suffix = originalFileName.substring(originalFileName.lastIndexOf('.') + 1, originalFileName.length()).toLowerCase();
                if(StringUtils.isBlank(defineName)){
                	fileName = UUID.randomUUID().toString();
                }else{
                	fileName = defineName;
                }
                
                String rfPath = null, lgcPath = null;
                try {
                	if("jpg".equals(suffix) || "gif".equals(suffix) 
                			|| "png".equals(suffix) || "jpeg".equals(suffix) 
                			|| "bmp".equals(suffix) || "tif".equals(suffix) 
                			|| "xls".equals(suffix) || "xlsx".equals(suffix)
                			|| "rtf".equals(suffix) || "tif".equals(suffix)
                			|| "doc".equals(suffix) || "docx".equals(suffix)
                			|| "rar".equals(suffix) || "zip".equals(suffix)) {
                		
                		String path = filePath +"/"+fileName+"."+suffix;
                		
						FileUtils.copyFile(file.getInputStream(), path);
						
						uploadPath += fileName+"."+suffix;
						rfPath = uploadPath;
						lgcPath = "/docfile" + uploadPath.substring(7).replace(".", "/") + ".html";
                		model.put("fileName", fileNew + "." + suffix);
                	} else if("pdf".equals(suffix)){
                		String path = filePath + "/" + fileName + "." + suffix;
                		File localFile = new File(path);
                		file.transferTo(localFile);
                		uploadPath += fileName + "." + suffix;
                		rfPath= uploadPath;
						lgcPath = "/docfile" + uploadPath.substring(7).replace(".", "/") + ".html";
                		model.put("fileName", fileNew + "." + suffix);
                	}else{
                		throw new Exception("不支持此文件格式：" + suffix);
                	}
                	
                	model.put("logicPath", lgcPath);
					model.put("filePath", rfPath);
					model.put("msg", "文件已经成功上传");
					return success(model);
				} catch (Exception e) {
					e.printStackTrace();
					logger.error("上传出错", e);
					model.put("msg", e.getMessage());
					return fail(e.getMessage());
				}
			}
	    }
	    
	    return fail("上传出错");
	}
	
	
	
	/**
	 * 删除硬盘文件
	 */
	@RequestMapping(value = "/file/delFiles", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> delFiles(HttpServletRequest request, HttpServletResponse response, 
			@RequestParam(value = "paths", required = false)String realPaths) {
		
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("status", 1);
		
		try{
			if(StringUtils.isBlank(realPaths)){
				model.put("msg", "请选择删除文件");
				fail("请选择删除文件");
				return model;
			}
			
			boolean b = false;
			String filePath = FilePropertyUtil.getFilePathProperty().getProperty("temPath");
			
			//删除部分
			String[] realPath=realPaths.split(",");
			for (int i = 0; i < realPath.length; i++) {
				if(StringUtils.isNotBlank(realPath[i])){
					File delFile = new File(filePath+realPath[i]);
		            //判断文件是否存在
		            if (delFile.exists()) {
		                b = delFile.delete();
		            }
				}
			}
            
            if (b){
            	model.put("status", 0);
                model.put("msg","删除文件成功");
                success(model);
            }else{
                model.put("msg","删除文件出错");
				fail("删除文件出错");
            }
		} catch (Exception e){
			e.printStackTrace();
			model.put("msg", e.getMessage());
			fail(e.getMessage());
		}
		
		return model;
	}
	
	
	
	/**
	 * 从硬盘下载文件
	 */
	@RequestMapping(value = "/docfile/{year}/{month}/{day}/{filename}/{type}", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> docfile(HttpServletRequest request, HttpServletResponse response, 
			@PathVariable String year, @PathVariable String month, @PathVariable String day, 
			@PathVariable String filename, @PathVariable String type, String name) {
		
		String logicPath = "/docfile/" + year + "/" + month + "/" + day + "/" + filename + "/" + type + "." + "html";
		name = Validator.isNullOrEmpty(name) ? uploadFileService.selectFileNameByLogicPath(logicPath) : name;
		try {
			name = URLEncoder.encode(name, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		response.setHeader("content-type", "application/octet-stream");
		response.setContentType("application/octet-stream");
		response.setHeader("Content-Disposition", "attachment;filename*=utf-8'zh_cn'" + name);
		
		String contextRealPath = FilePropertyUtil.getFilePathProperty().getProperty("temPath");
		String pathname = contextRealPath + "/upload/" + year + "/" + month + "/" + day + "/" + filename + "." + type;
		
		try (InputStream inputStream = 
				new FileInputStream(new File(pathname))){
			
			byte[] b = new byte[1024];
			int len = -1;
			OutputStream outputStream = response.getOutputStream();
			
			while ((len = inputStream.read(b)) != -1) {
				// 向输出流中输出pdf文件
				// 读取字节，从0到len长度
				outputStream.write(b, 0, len);
			}
			
			outputStream.flush();
			outputStream.close();
		} catch(Exception e){
			e.printStackTrace();
		}
		
		return null;
	}
	
    
	
	
	
    public static String invokeProcessForOpenOrder(String url, String path, String fileName) {
    	
		ProcessBuilder builder = null;
		Graphics graphics = null;
		
		try {
			Date date = new Date();
			File dirPath = new File(path);
	        if (!dirPath.exists()) {
	            dirPath.mkdirs();
	        }
	        String imgPath = path + fileName;
	        
			builder = new ProcessBuilder("/home/shells/runCutyCapt.sh", url, imgPath);
			Process p = builder.start();
			p.waitFor();
			
			String fullImgPath  = imgPath + ".jpg";
			File f = new File(fullImgPath);
			if(!f.exists()){
				return null;
			}
			
			BufferedImage bi = ImageIO.read(f);
			graphics = bi.getGraphics();
	        graphics.setColor(new Color(168, 0, 0));
	        graphics.fillRect(0, 0, bi.getWidth() / 3, 20);
	        graphics.drawRect(0, 0, bi.getWidth() / 3, 20);
	        graphics.setFont(new Font("TimesRoman", Font.BOLD, 20));
	        String content = new String(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
	        graphics.setColor(new Color(255, 255, 255));
	        graphics.drawString(content, 20, 20);
	        ImageIO.write(bi, "jpg", f);

	        if(fullImgPath.indexOf("/snapshot/open") > 0){
	        	fullImgPath = fullImgPath.substring(fullImgPath.indexOf("/snapshot/open"));
	    	}else if(fullImgPath.indexOf("/snapshot/article") > 0){
	    		fullImgPath = fullImgPath.substring(fullImgPath.indexOf("/snapshot/article"));
	    	}
	        return fullImgPath;
		} catch (Exception e) {
			logger.error("截图出错", e);
		} finally{
			if(graphics != null){
				graphics.dispose();
			}
		}
		
		return null;
	}
    
    
    
    public static boolean pressText(String pressText, String targetImg, String fontName, 
    		int fontStyle, int color, int fontSize, int x, int y, String outPath) { 
    	
    	boolean isSucc = false;
    	
    	try {
    		
    		File file = new File(targetImg);
    		Image src = ImageIO.read(file);
    		int width = src.getWidth(null);
    		int height = src.getHeight(null);
    		if(width > 200 && height > 200) {
    			BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	    		Graphics g = image.createGraphics();
	    		g.drawImage(src, 0, 0, width, height, null);
	    		g.setColor(new Color(color));
	    		g.setFont(new Font(fontName, fontStyle, fontSize));
	    		g.drawString(pressText, width - fontSize - x, height - fontSize / 2 - y);
	    		g.dispose();
	    		OutputStream out = new FileOutputStream(outPath);
	    		out.close();
	    		isSucc = true;
    		}
    		
    	} catch (Exception e) {
    		logger.error("打码出错", e);
    	}
    	
		return isSucc;
    }
    
}
